package com.vcc.service.impl;

import com.mybatisflex.core.paginate.Page;
import com.mybatisflex.core.query.QueryChain;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import com.vcc.core.exception.NotFoundException;
import com.vcc.core.util.DateUtil;
import com.vcc.core.util.RegexUtil;
import com.vcc.data.entity.Role;
import com.vcc.data.entity.TaskLog;
import com.vcc.data.entity.User;
import com.vcc.data.mapper.TaskLogMapper;
import com.vcc.service.boss.response.taskLog.BossTaskLogVoBoss;
import com.vcc.service.client.vo.taskLog.TaskLogVo;
import com.vcc.service.sa.BossUserUtil;
import com.vcc.service.service.TaskLogService;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

import static com.vcc.data.entity.table.BossUserTableDef.BOSS_USER;
import static com.vcc.data.entity.table.TaskLogInfoTableDef.TASK_LOG_INFO;
import static com.vcc.data.entity.table.TaskLogTableDef.TASK_LOG;
import static com.vcc.data.entity.table.UserTableDef.USER;

@Service
public class TaskLogServiceImpl extends ServiceImpl<TaskLogMapper, TaskLog> implements TaskLogService {

    @Override
    public Boolean processedSuccess(String orderId) {
//        return updateChain().eq(TaskLog::getOrderId, orderId).set(TASK_LOG,"processed_success_count = processed_success_count + 1").update();
        return true;
    }


    @Override
    public Boolean processedError(String orderId) {
//        return updateChain().eq(TaskLog::getOrderId, orderId).setSql("processed_error_count = processed_error_count + 1").update();
        return true;
    }

    @Override
    public Boolean processedAccomplish(String orderId) {
        TaskLog taskLog = queryChain().eq(TaskLog::getOrderId, orderId).one();
        return updateChain().eq(TaskLog::getOrderId, orderId)
                .set(TaskLog::getStatus, 0)
                .update();
    }

    @Override
    public Boolean processedAccomplish(Long id) {
        return updateChain().eq(TaskLog::getId, id)
                .set(TaskLog::getStatus, 0)
                .set(TaskLog::getCompletionDate, new Date())
                .update();
    }

    @Override
    public List<TaskLog> listByStatus(Integer status, Long userId) {
        return queryChain().eq(TaskLog::getStatus, status).eq(TaskLog::getUserId, userId).list();
    }

    @Override
    public Page<TaskLogVo> clientPaging(Integer pageNumber, Integer pageSize, Role role, Long userId, Long targetUserId, Integer status, String startDate, String endDate,Integer useFlag) {
        QueryChain<TaskLog> queryChain = queryChain();
        queryChain.select(TASK_LOG.ALL_COLUMNS);
        queryChain.select(USER.EMAIL.as("account"));
        //查询关联表TASK_LOG_INFO 得 count successCount errorCount
        queryChain.select("COUNT(taskLogInfo.id) AS count");
        queryChain.select("SUM(CASE WHEN taskLogInfo.status = 0 THEN 1 ELSE 0 END) AS processedSuccessCount");
        queryChain.select("SUM(CASE WHEN taskLogInfo.status = 1 THEN 1 ELSE 0 END) AS processedErrorCount");
        queryChain.leftJoin(USER).on(USER.ID.eq(TASK_LOG.USER_ID));
        queryChain.leftJoin(TASK_LOG_INFO.as("taskLogInfo")).on(TASK_LOG_INFO.as("taskLogInfo").TASK_ID.eq(TASK_LOG.ID));
        if (role.getHasAllData()) {
            queryChain.where(
                    USER.PARENT_ID.eq(userId).or(USER.ID.eq(userId))
            );
            if (RegexUtil.checkObjectIsNotNull(targetUserId)) {
                queryChain.where(TASK_LOG.USER_ID.eq(targetUserId));
            }
        } else {
            queryChain.where(TASK_LOG.USER_ID.eq(userId));
        }
        if (RegexUtil.checkObjectIsNotNull(status)) {
            queryChain.where(TASK_LOG.STATUS.eq(status));
        }
        if (RegexUtil.checkObjectIsNotNull(startDate)) {
            queryChain.where(TASK_LOG.REQUEST_DATE.gt(DateUtil.getDayBeginDate(startDate, "yyyy-MM-dd")));
        }
        if (RegexUtil.checkObjectIsNotNull(endDate)) {
            queryChain.where(TASK_LOG.REQUEST_DATE.lt(DateUtil.getDayEndDate(endDate, "yyyy-MM-dd")));
        }
        if (RegexUtil.checkObjectIsNotNull(useFlag)) {
            queryChain.where(TASK_LOG.USE_FLAG.eq(useFlag));
        }
        queryChain.groupBy(TASK_LOG.ID);
        queryChain.orderBy(TASK_LOG.REQUEST_DATE.desc());
        return pageAs(
                Page.of(
                        pageNumber == null || pageNumber < 1 ? 1 : pageNumber,
                        pageSize == null || pageSize < 1 ? 10 : pageSize
                ),
                queryChain,
                TaskLogVo.class
        );
    }


    @Override
    public Page<BossTaskLogVoBoss> bossPaging(Integer pageNumber, Integer pageSize, String orderId, Long targetUserId, Integer status, String startDate, String endDate, Integer useFlag) {
        QueryChain<TaskLog> queryChain = queryChain();
        queryChain.select(TASK_LOG.ALL_COLUMNS);
        queryChain.select(USER.as("user").EMAIL.as("account"));
        queryChain.select(BOSS_USER.as("dealer").EMAIL.as("dealerAccount"));
        queryChain.select("COUNT(taskLogInfo.id) AS count");
        queryChain.select("SUM(CASE WHEN taskLogInfo.status = 0 THEN 1 ELSE 0 END) AS processedSuccessCount");
        queryChain.select("SUM(CASE WHEN taskLogInfo.status = 1 THEN 1 ELSE 0 END) AS processedErrorCount");
        queryChain.select("(select email from vcc_user where id = user.parent_id limit 1) as parentAccount");
        queryChain.leftJoin(USER.as("user")).on(USER.as("user").ID.eq(TASK_LOG.USER_ID));
        queryChain.leftJoin(BOSS_USER.as("dealer")).on(BOSS_USER.as("dealer").ID.eq(USER.as("user").BE_LONG_TO_DEALER));
        queryChain.leftJoin(TASK_LOG_INFO.as("taskLogInfo")).on(TASK_LOG_INFO.as("taskLogInfo").TASK_ID.eq(TASK_LOG.ID));
        Long bossUserId = BossUserUtil.getIdNotNull();
        if (!BossUserUtil.hasAllData()) {
            queryChain.and(
                    BOSS_USER.as("dealer").ID.eq(bossUserId)
                            .or(BOSS_USER.as("dealer").PARENT_ID.eq(bossUserId))
            );
        }
        if (RegexUtil.checkObjectIsNotNull(targetUserId)) {
            queryChain.eq(User::getId, targetUserId);
        }
        if (RegexUtil.checkObjectIsNotNull(status)) {
            queryChain.where(TASK_LOG.STATUS.eq(status));
        }
        if (RegexUtil.checkObjectIsNotNull(startDate)) {
            queryChain.where(TASK_LOG.REQUEST_DATE.gt(DateUtil.getDayBeginDate(startDate, "yyyy-MM-dd")));
        }
        if (RegexUtil.checkObjectIsNotNull(endDate)) {
            queryChain.where(TASK_LOG.REQUEST_DATE.lt(DateUtil.getDayEndDate(endDate, "yyyy-MM-dd")));
        }
        if (RegexUtil.checkObjectIsNotNull(useFlag)) {
            queryChain.where(TASK_LOG.USE_FLAG.eq(useFlag));
        }
        if (RegexUtil.checkObjectIsNotNull(orderId)) {
            queryChain.where(TASK_LOG.ORDER_ID.eq(orderId));
        }
        queryChain.groupBy(TASK_LOG.ID);
        queryChain.orderBy(TASK_LOG.REQUEST_DATE.desc());
        return pageAs(
                Page.of(
                        pageNumber == null || pageNumber < 1 ? 1 : pageNumber,
                        pageSize == null || pageSize < 1 ? 10 : pageSize
                ),
                queryChain,
                BossTaskLogVoBoss.class
        );
    }

    @Override
    public TaskLogVo getById(Long id) {
        QueryChain<TaskLog> queryChain = queryChain();
        queryChain.select(TASK_LOG.ALL_COLUMNS);
        queryChain.select(USER.EMAIL.as("account"));
        //查询关联表TASK_LOG_INFO 得 count successCount errorCount
        queryChain.select("COUNT(taskLogInfo.id) AS count");
        queryChain.select("SUM(CASE WHEN taskLogInfo.status = 0 THEN 1 ELSE 0 END) AS processedSuccessCount");
        queryChain.select("SUM(CASE WHEN taskLogInfo.status = 1 THEN 1 ELSE 0 END) AS processedErrorCount");
        queryChain.leftJoin(USER).on(USER.ID.eq(TASK_LOG.USER_ID));
        queryChain.leftJoin(TASK_LOG_INFO.as("taskLogInfo")).on(TASK_LOG_INFO.as("taskLogInfo").TASK_ID.eq(TASK_LOG.ID));
        queryChain.where(TASK_LOG.ID.eq(id));
        return getOneAsOpt(queryChain, TaskLogVo.class).orElseThrow(() -> new NotFoundException("任务日志不存在"));
    }

    @Override
    public BossTaskLogVoBoss getBossById(Long id) {
        QueryChain<TaskLog> queryChain = queryChain();
        queryChain.select(TASK_LOG.ALL_COLUMNS);
        queryChain.select(USER.as("user").EMAIL.as("account"));
        queryChain.select(BOSS_USER.as("dealer").EMAIL.as("dealerAccount"));
        queryChain.select("COUNT(taskLogInfo.id) AS count");
        queryChain.select("SUM(CASE WHEN taskLogInfo.status = 0 THEN 1 ELSE 0 END) AS processedSuccessCount");
        queryChain.select("SUM(CASE WHEN taskLogInfo.status = 1 THEN 1 ELSE 0 END) AS processedErrorCount");
        queryChain.select("(select email from vcc_user where id = user.parent_id limit 1) as parentAccount");
        queryChain.leftJoin(USER.as("user")).on(USER.as("user").ID.eq(TASK_LOG.USER_ID));
        queryChain.leftJoin(BOSS_USER.as("dealer")).on(BOSS_USER.as("dealer").ID.eq(USER.as("user").BE_LONG_TO_DEALER));
        queryChain.leftJoin(TASK_LOG_INFO.as("taskLogInfo")).on(TASK_LOG_INFO.as("taskLogInfo").TASK_ID.eq(TASK_LOG.ID));
        Long bossUserId = BossUserUtil.getIdNotNull();
        if (!BossUserUtil.hasAllData()) {
            queryChain.and(
                    BOSS_USER.as("dealer").ID.eq(bossUserId)
                            .or(BOSS_USER.as("dealer").PARENT_ID.eq(bossUserId))
            );
        }
        queryChain.where(TASK_LOG.ID.eq(id));
        return getOneAsOpt(queryChain, BossTaskLogVoBoss.class).orElseThrow(() -> new NotFoundException("任务日志不存在"));
    }
}
